﻿using Microsoft.EntityFrameworkCore;
using Work.Domain;
using Work.Domain.DrugManage;

namespace Work.Infrastructure
{
    public class ConDbContext : DbContext
    {
        public ConDbContext(DbContextOptions options) : base(options)
        {
        }

       //就诊人
       public DbSet<Patient> Patients { get; set; }
       //预约信息
       public DbSet<Appintment> Appintments { get; set; }
       //病历信息
       public DbSet<MedicalRecord> MedicalRecords { get; set; }
       //处方明细
       public DbSet<PrescriptionItem> PrescriptionItems { get; set; }
       //支付记录
       public DbSet<Payment> Payments { get; set; }
        public DbSet<User> Users { get; set; }
       //药品基础信息
       public DbSet<Drug> Drugs { get; set; }
       //药品入库记录
       public DbSet<DrugInbound> DrugInbounds { get; set; }
       //药品出库记录
       public DbSet<DrugOutbound> DrugOutbounds { get; set; }
       //检药单
       public DbSet<DrugInspection> DrugInspections { get; set; }

       protected override void OnModelCreating(ModelBuilder modelBuilder)
       {
           base.OnModelCreating(modelBuilder);

           // 配置 Appintment 和 MedicalRecord 的一对一关系
           modelBuilder.Entity<Appintment>()
               .HasOne(a => a.MedicalRecord)
               .WithOne(m => m.Appointment)
               .HasForeignKey<MedicalRecord>(m => m.AppointmentId)
               .OnDelete(DeleteBehavior.Restrict);

           // 配置 Appintment 和 Patient 的关系
           modelBuilder.Entity<Appintment>()
               .HasOne(a => a.Patient)
               .WithMany()
               .HasForeignKey(a => a.PatientId)
               .OnDelete(DeleteBehavior.Restrict);

           // 配置 MedicalRecord 和 Patient 的关系
           modelBuilder.Entity<MedicalRecord>()
               .HasOne(m => m.Patient)
               .WithMany()
               .HasForeignKey(m => m.PatientId)
               .OnDelete(DeleteBehavior.Restrict);

           // 配置索引
           modelBuilder.Entity<Appintment>()
               .HasIndex(a => a.CardNumber);
           
           modelBuilder.Entity<Appintment>()
               .HasIndex(a => a.VisitDate);
           
           modelBuilder.Entity<Appintment>()
               .HasIndex(a => a.DoctorName);

           modelBuilder.Entity<MedicalRecord>()
               .HasIndex(m => m.AppointmentId)
               .IsUnique();
           
           modelBuilder.Entity<MedicalRecord>()
               .HasIndex(m => m.PatientId);

           // 配置 PrescriptionItem 关系
           modelBuilder.Entity<PrescriptionItem>()
               .HasOne(pi => pi.Appointment)
               .WithMany()
               .HasForeignKey(pi => pi.AppointmentId)
               .OnDelete(DeleteBehavior.Restrict);

           modelBuilder.Entity<PrescriptionItem>()
               .HasOne(pi => pi.MedicalRecord)
               .WithMany()
               .HasForeignKey(pi => pi.RecordId)
               .OnDelete(DeleteBehavior.Restrict);

           modelBuilder.Entity<PrescriptionItem>()
               .HasOne(pi => pi.Patient)
               .WithMany()
               .HasForeignKey(pi => pi.PatientId)
               .OnDelete(DeleteBehavior.Restrict);

           // 配置 Payment 关系
           modelBuilder.Entity<Payment>()
               .HasOne(p => p.Appointment)
               .WithMany()
               .HasForeignKey(p => p.AppointmentId)
               .OnDelete(DeleteBehavior.Restrict);

           modelBuilder.Entity<Payment>()
               .HasOne(p => p.Patient)
               .WithMany()
               .HasForeignKey(p => p.PatientId)
               .OnDelete(DeleteBehavior.Restrict);

           // 配置索引
           modelBuilder.Entity<PrescriptionItem>()
               .HasIndex(pi => pi.AppointmentId);

           // 注意：PaymentStatus是longtext类型，MySQL不支持直接索引
           // 如果需要频繁查询，建议在应用层过滤或考虑使用varchar(50)类型

           modelBuilder.Entity<Payment>()
               .HasIndex(p => p.AppointmentId);

           // 注意：PaymentStatus是longtext类型，MySQL不支持直接索引
           // 如果需要频繁查询，建议在应用层过滤或考虑使用varchar(50)类型

           // ============================================
           // 药品管理模块配置
           // ============================================

           // 1. Drug（药品基础信息表）配置
           // 药品名称索引，用于快速查询
           modelBuilder.Entity<Drug>()
               .HasIndex(d => d.DrugName);

           // 药品类型索引，用于分类查询
           modelBuilder.Entity<Drug>()
               .HasIndex(d => d.DrugType);

           // 复合索引，用于按名称和类型查询
           modelBuilder.Entity<Drug>()
               .HasIndex(d => new { d.DrugName, d.DrugType });

           // 2. DrugInbound（药品入库记录表）配置
           // 外键关系，删除药品时限制删除入库记录
           modelBuilder.Entity<DrugInbound>()
               .HasOne(di => di.Drug)
               .WithMany()
               .HasForeignKey(di => di.DrugId)
               .OnDelete(DeleteBehavior.Restrict);

           // 药品ID索引，用于关联查询
           modelBuilder.Entity<DrugInbound>()
               .HasIndex(di => di.DrugId);

           // 入库日期索引，用于时间范围查询
           modelBuilder.Entity<DrugInbound>()
               .HasIndex(di => di.InboundDate);

           // 复合索引，用于查询某药品的入库历史
           modelBuilder.Entity<DrugInbound>()
               .HasIndex(di => new { di.DrugId, di.InboundDate });

           // 3. DrugOutbound（药品出库记录表）配置
           // 外键关系：关联药品
           modelBuilder.Entity<DrugOutbound>()
               .HasOne(dout => dout.Drug)
               .WithMany()
               .HasForeignKey(dout => dout.DrugId)
               .OnDelete(DeleteBehavior.Restrict);

           // 外键关系：关联处方明细（可选外键）
           modelBuilder.Entity<DrugOutbound>()
               .HasOne(dout => dout.PrescriptionItem)
               .WithMany()
               .HasForeignKey(dout => dout.PrescriptionItemId)
               .OnDelete(DeleteBehavior.Restrict)
               .IsRequired(false);

           // 外键关系：关联预约（可选外键）
           modelBuilder.Entity<DrugOutbound>()
               .HasOne(dout => dout.Appointment)
               .WithMany()
               .HasForeignKey(dout => dout.AppointmentId)
               .OnDelete(DeleteBehavior.Restrict)
               .IsRequired(false);

           // 外键关系：关联患者
           modelBuilder.Entity<DrugOutbound>()
               .HasOne(dout => dout.Patient)
               .WithMany()
               .HasForeignKey(dout => dout.PatientId)
               .OnDelete(DeleteBehavior.Restrict);

           // 药品ID索引
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => dout.DrugId);

           // 患者ID索引，用于查询某患者的发药记录
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => dout.PatientId);

           // 卡号索引，用于快速查询（冗余字段）
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => dout.CardNumber);

           // 出库日期索引，用于时间范围查询
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => dout.OutboundDate);

           // 处方明细ID索引，用于追溯（可选字段，可以创建索引）
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => dout.PrescriptionItemId);

           // 复合索引，用于查询某患者在某个时间段的发药记录
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => new { dout.PatientId, dout.OutboundDate });

           // 复合索引，用于查询某药品的出库历史
           modelBuilder.Entity<DrugOutbound>()
               .HasIndex(dout => new { dout.DrugId, dout.OutboundDate });

           // 4. DrugInspection（检药单表）配置
           // 外键关系：关联处方明细（一个处方明细对应一个检药单）
           modelBuilder.Entity<DrugInspection>()
               .HasOne(di => di.PrescriptionItem)
               .WithMany()
               .HasForeignKey(di => di.PrescriptionItemId)
               .OnDelete(DeleteBehavior.Restrict);

           // 外键关系：关联预约
           modelBuilder.Entity<DrugInspection>()
               .HasOne(di => di.Appointment)
               .WithMany()
               .HasForeignKey(di => di.AppointmentId)
               .OnDelete(DeleteBehavior.Restrict);

           // 外键关系：关联患者
           modelBuilder.Entity<DrugInspection>()
               .HasOne(di => di.Patient)
               .WithMany()
               .HasForeignKey(di => di.PatientId)
               .OnDelete(DeleteBehavior.Restrict);

           // 外键关系：关联药品（可选外键）
           modelBuilder.Entity<DrugInspection>()
               .HasOne(di => di.Drug)
               .WithMany()
               .HasForeignKey(di => di.DrugId)
               .OnDelete(DeleteBehavior.Restrict)
               .IsRequired(false);

           // 唯一索引，确保一个处方明细只有一个检药单
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => di.PrescriptionItemId)
               .IsUnique();

           // 患者ID索引
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => di.PatientId);

           // 挂号编号索引，用于快速查询
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => di.RegistrationNum);

           // 检查状态索引，用于筛选待检查/已检查的记录
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => di.InspectionStatus);

           // 是否已发药索引，用于筛选未发药/已发药的记录
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => di.IsDispensed);

           // 创建时间索引，用于时间范围查询
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => di.CreateTime);

           // 复合索引，用于查询某患者的未发药检药单，按时间排序
           modelBuilder.Entity<DrugInspection>()
               .HasIndex(di => new { di.PatientId, di.IsDispensed, di.CreateTime });

           // ============================================
           // 药品管理模块配置结束
           // ============================================
       }
    }
}
